package org.clever.dynamic.datasource.service;

import lombok.extern.slf4j.Slf4j;
import org.clever.dynamic.datasource.annotation.DataSource;
import org.clever.dynamic.datasource.entity.UserRole;
import org.clever.dynamic.datasource.mapper.RolePermissionMapper;
import org.clever.dynamic.datasource.mapper.UserRoleMapper;
import org.clever.dynamic.datasource.mapper.UserSysMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 作者： lzw<br/>
 * 创建时间：2018-11-09 15:54 <br/>
 */
@Transactional(readOnly = true)
@Service
@Slf4j
public class TestService {

    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private UserSysMapper userSysMapper;

    /**
     * 只读
     */
    @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
    @DataSource("slave_1")
    public Object read() {
        return rolePermissionMapper.get("read", "read");
    }

    /**
     * 只写
     */
    @DataSource("master")
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Object write() {
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        return userRoleMapper.insert(userRole);
    }

    /**
     * 先写在读
     */
    @Transactional
    public Object writeAndRead() {
        // 写主库
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        log.info("### 写 {}", userRoleMapper.insert(userRole));
        // 读主库
        return userSysMapper.selectList(null);
    }

    /**
     * 先读在写
     */
    @Transactional
    public Object readAndWrite() {
        // 读从库
        log.info("### 读 {}", userSysMapper.selectList(null));
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        // 写主库
        return userRoleMapper.insert(userRole);
    }

    /**
     * 写 - 读 - 写
     */
    @Transactional
    public Object writeAndReadAndWrite() {
        // 写主库
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        log.info("### 写 {}", userRoleMapper.insert(userRole));
        // 读主库
        log.info("### 读 {}", userSysMapper.selectList(null));
        // 写主库
        userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        return userRoleMapper.insert(userRole);
    }

    /**
     * 写 - 读 - 读 - 写
     */
    @Transactional
    public Object writeAndReadsAndWrite() {
        // 写主库
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        log.info("### 写 {}", userRoleMapper.insert(userRole));
        // 读主库
        log.info("### 读 {}", userSysMapper.selectList(null));
        log.info("### 读 {}", userSysMapper.selectList(null));
        // 写主库
        userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        return userRoleMapper.insert(userRole);
    }

    /**
     * 读 - 写 - 读
     */
    @Transactional
    public Object readAndWriteAndRead() {
        // 读从库
        log.info("### 读 {}", userSysMapper.selectList(null));
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        // 写主库
        log.info("### 写 {}", userRoleMapper.insert(userRole));
        return userSysMapper.selectList(null);
    }

    /**
     * 读 - 写 - 写 - 读
     */
    @Transactional
    public Object readAndWritesAndRead() {
        // 读从库
        log.info("### 读 {}", userSysMapper.selectList(null));
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        // 写主库
        log.info("### 写 {}", userRoleMapper.insert(userRole));
        log.info("### 写 {}", userRoleMapper.insert(userRole));
        return userSysMapper.selectList(null);
    }

    /**
     * 强制在写库读
     */
    public Object forceReadInWrite() {
        // HintManager.getInstance().setMasterRouteOnly();
        log.info("### 读 {}", userSysMapper.selectList(null));
        log.info("### 读 {}", userSysMapper.selectList(null));
        return userSysMapper.selectList(null);
    }

    /**
     * 在@Select中insert
     */
    @Transactional
    public Object insertBySelect() {
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        Integer count = userRoleMapper.insertBySelect(userRole);
        log.info("### 在@Select中insert -> {}", count);
        return count;
    }

    @Transactional
    public Object insertBySelect2() {
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        userRoleMapper.insertBySelect2(userRole);
        log.info("### 在@Select中insert -> null");
        return null;
    }

    @Transactional
    public Object nativeSql() {
        UserRole userRole = new UserRole();
        userRole.setRoleName("write");
        userRole.setUsername("write");
        userRoleMapper.nativeSql(userRole);
        log.info("### nativeSql -> null");
        return null;
    }
}
